Фінальний проєкт¶


Створив: Лукʼянець Іван

Поставлені цілі проєкту¶

  • Дослідити статево-віковий склад населення села Дунаєць у 1897 і 1778 роках
  • Розглянути соціальні стани в двох переписах
  • Детально дослідити стан "козацтво" на основні заняття, грамотність, освіту.
In [545]:
import pandas as pd
import numpy as np
import altair as alt
import matplotlib.pyplot as plt

Статево-віковий склад населення¶

Обробка та робота з даними

In [546]:
d_1897 = pd.read_csv("Final_DME/2.1_Дунаєць.xlsx - База людей.csv")
d_1897.dropna(subset=["Возраст"],inplace=True)
d_1897.loc[d_1897["Возраст"].str.contains("month"),"Возраст"] = "0" # Замінюємо дані малюків і новонародженим на 0 років
d_1897.loc[d_1897["Возраст"].str.contains("week"),"Возраст"] = "0"
d_1897.loc[d_1897["Возраст"].str.contains("days"),"Возраст"] = "0"
d_1897 = d_1897.reindex(columns=["Возраст","Пол"])
d_1897["Year"] = "1897"
d_1897.rename(columns ={"Возраст" : "Age", "Пол" : "Sex"}, inplace=True)
d_1897.loc[d_1897["Sex"] == "m"]["Age"].astype(float).mean() # 26.63307493540052 Cердній вік чоловіка 1897
d_1897.loc[d_1897["Sex"] == "f"]["Age"].astype(float).mean() # 24.2094682230869 Cердній вік жінки 1897
d_1897
Out[546]:
Age Sex Year
0 32 m 1897
1 28 f 1897
2 5 f 1897
3 1 m 1897
4 70 m 1897
... ... ... ...
1543 30 f 1897
1544 9 f 1897
1545 7 m 1897
1546 5 m 1897
1547 3 m 1897

1545 rows × 3 columns

In [547]:
d_1778 = pd.read_csv("Final_DME/2.2_Дунаєць_1778.xlsx - База.csv") 
new_columns = d_1778.loc[2]
new_columns.iloc[0] = "Аркуш"
new_columns.iloc[4] = "Наскрізне Чоловіки"
new_columns.iloc[5] = "Наскрізне Жінки"
new_columns.iloc[6] = "Число людей джерело Чоловіки"
new_columns.iloc[7] = "Число людей джерело Жінки"
d_1778.columns = d_1778.loc[2]
d_1778.rename(columns={np.nan: "Аркуш"},inplace=True)
d_1778.drop(index=[0,1,2],inplace=True)
d_1778["Sex"] = pd.NA
d_1778.loc[d_1778["Число людей джерело Чоловіки"].notna(),"Sex"] = "m" # Визначаємо стать людини
d_1778.loc[d_1778["Число людей джерело Жінки"].notna(),"Sex"] = "f"
d_1778 = d_1778.reindex(columns=["Вік","Sex"])
d_1778["Year"] = "1778"
d_1778.rename(columns={"Вік" : "Age"},inplace=True)
d_1778.loc[d_1778["Sex"] == "m"]["Age"].astype(float).mean() # 23.559322033898304 Cердній вік чоловіка 1778
d_1778.loc[d_1778["Sex"] == "f"]["Age"].astype(float).mean() # 23.49805447470817 Cердній вік жінки 1778
d_1778
Out[547]:
2 Age Sex Year
3 44 m 1778
4 35 f 1778
5 17 f 1778
6 15 m 1778
7 14 m 1778
... ... ... ...
1595 25 m 1778
1596 22 f 1778
1597 43 m 1778
1598 42 f 1778
1599 14 m 1778

1597 rows × 3 columns

In [548]:
population = pd.concat([d_1897, d_1778], axis=0,ignore_index=True)
population["Age"] = population["Age"].astype(float)
population # Фінальний датасет для візуалізації
Out[548]:
Age Sex Year
0 32.0 m 1897
1 28.0 f 1897
2 5.0 f 1897
3 1.0 m 1897
4 70.0 m 1897
... ... ... ...
3137 25.0 m 1778
3138 22.0 f 1778
3139 43.0 m 1778
3140 42.0 f 1778
3141 14.0 m 1778

3142 rows × 3 columns

Візуалізація даних

In [559]:
years=alt.binding_select(name='Year: ',options=['1778','1897'])
selection = alt.param(name='year', bind=years,value="1778")

female = alt.Chart(population).mark_bar().encode(
    x=alt.X('count(Sex):Q',scale=alt.Scale(domain=(0,45)),title='Population'),
    y=alt.Y('Age:Q',axis=None,scale=alt.Scale(domain=(0,95))),
    color=alt.value('#FF69B4'),
    tooltip=["Age",'count(Sex)']
).properties(height=400,width=400,title="Female").transform_filter(alt.datum.Sex == 'f').transform_filter(
    alt.datum.Year==selection
).add_params(selection)

male = alt.Chart(population).mark_bar().encode(
    x=alt.X('count(Sex):Q', scale=alt.Scale(reverse=True,domain=(0,45)),title='Population'),
    y=alt.Y('Age:Q',axis=None,scale=alt.Scale(domain=(0,100))),
    color=alt.value('#0096FF'),
    tooltip=["Age",'count(Sex)']
).properties(height=400,width=400,title="Male").transform_filter(alt.datum.Sex == 'm').transform_filter(
    alt.datum.Year==selection
).add_params(selection)

ages = pd.DataFrame(np.arange(0,100,5))
ages.columns = ["Age"]

y_bar = alt.Chart(ages).encode(
    y=alt.Y('Age:Q', axis=None,scale=alt.Scale(domain=(0,100))),
    text=alt.Text('Age:Q'),
).mark_text()
alt.concat(male, y_bar, female, spacing=5).resolve_scale(y='shared')
Out[559]:

Аналіз результатів¶

  • Село Дунаєць має другий тип відтворення населення у обох переписах, бо ми можемо візуально побачити піраміду правильної трикутної форми. Зазвичай суспільства з таким типом відтворення мають наступні проблеми: нестача харчування, неписемність, безробіття.
  • Упродовж 119 років зріс середній вік жителя села. Для чоловіків з 23,5 до 26,6. Для жінок з 23,4 до 24,2. Також візуально піраміда 1897 стала довшою, що означає збільшення тривалості життя.
  • На піраміді 1897 року, помітні викревлення даних(горизонтальні прямі, які виділяються 25,30,35,40,45,50,55). Це повʼязано з неписемністю дорослого населення та бажанням бути старшим. Більш явно це можна побачити на загальному всеросійському переписі 1897. Чому у переписі 1778 вони відсутні або їх мало? Перепис 1778 вела церква, і можливо вони мали дати хрещення людей. На це є історичне підґрунтя, бо з 1720 року влада російської імперії заохочуала вести книги з похрещеними людьми.

Соціальні статуси¶

Обробка та робота з даними

In [550]:
d_1897 = pd.read_csv("Final_DME/2.1_Дунаєць.xlsx - База людей.csv")
c_1897 = d_1897["Сословие, состояние или звание"].value_counts()
c_1897 = pd.DataFrame(c_1897)
c_1897["Percentage"] = ((c_1897["count"] / c_1897["count"].sum() * 100).round(2)).astype(str) + "%" # Відсотковий розподіл верст населення 1897
c_1897.rename(index={"cossack" : "Козаки",
        "peasant-owner" : "Посполиті",
        "dukhovnogo" : "Духовенство",
        "imenuyushchijsya dvoryanin" : "Називає себе дворянином",
        "citizen" : "Міщани",
        "state peasant" : "Державні селяни",
        "nobles" : "Дворяни",
        "dvorovyj" : "Прислуга"},
             inplace=True)
c_1897
Out[550]:
count Percentage
Сословие, состояние или звание
Козаки 871 56.38%
Посполиті 639 41.36%
Духовенство 13 0.84%
Називає себе дворянином 9 0.58%
Міщани 7 0.45%
Державні селяни 3 0.19%
Дворяни 2 0.13%
Прислуга 1 0.06%
In [551]:
d_1778 = pd.read_csv("Final_DME/2.2_Дунаєць_1778.xlsx - База.csv") 
new_columns = d_1778.loc[2]
new_columns.iloc[0] = "Аркуш"
new_columns.iloc[4] = "Наскрізне Чоловіки"
new_columns.iloc[5] = "Наскрізне Жінки"
new_columns.iloc[6] = "Число людей джерело Чоловіки"
new_columns.iloc[7] = "Число людей джерело Жінки"
d_1778.columns = d_1778.loc[2]
d_1778.rename(columns={np.nan: "Аркуш"},inplace=True)
d_1778.drop(index=[0,1,2],inplace=True)
d_1778["Sex"] = pd.NA
d_1778.loc[d_1778["Число людей джерело Чоловіки"].notna(),"Sex"] = "m" 
d_1778.loc[d_1778["Число людей джерело Жінки"].notna(),"Sex"] = "f"
c_1778 = d_1778["Соціальний статус"].value_counts()
c_1778 = pd.DataFrame(c_1778)
c_1778["Percentage"] = ((c_1778["count"] / c_1778["count"].sum()) * 100).round(2) # Відсотковий розподіл верст населення 1778
c_1778.rename(index={"военные" : "Козаки",
                     "посполитые" : "Посполиті",
                     "бездворные" : "Бездворні",
                     "дворовые" : "Прислуга(Кріпаки)",
                     "духовные" : "Духовенство"} , inplace=True)
c_1778
Out[551]:
count Percentage
Соціальний статус
Козаки 727 45.55
Посполиті 710 44.49
Бездворні 84 5.26
Прислуга(Кріпаки) 64 4.01
Духовенство 11 0.69

Візуалізація даних

In [552]:
fig, axes = plt.subplots(2,dpi=400)
axes[0].pie(c_1778["count"],labels=c_1778.index,
            autopct='%1.1f%%',
            colors=["#E69F00","#56B4E9","#009E73","#F0E442","#0072B2"],
            pctdistance=0.8,
            textprops=dict(size=12,weight=1000,fontname="Arial"))
axes[0].set_title("1778", size=23,fontname="Arial")
hex_colors = [
    "#E69F00",  
    "#56B4E9", 
    "#0072B2",  
    "#000000",  
    "#009E73",  
    "#D55E00", 
    "#CC79A7",  
    "#F0E442",  
]

bars = axes[1].barh(c_1897.index,np.sqrt(c_1897["count"]),color=hex_colors)
axes[1].set_title("1897", size=23,fontname="Arial")
axes[1].set_xlabel("$\\sqrt{популяція}$",fontname="Arial",size=12,weight=1000)
for label in axes[1].get_yticklabels():
    label.set_fontsize(12)
    label.set_fontname("Arial")
    label.set_fontweight(1000)

for label in axes[1].get_xticklabels():
    label.set_fontsize(12)
    label.set_fontname("Arial")
    label.set_fontweight(1000)

axes[1].spines['bottom'].set_color('white')
axes[1].spines['top'].set_color('white') 
axes[1].spines['right'].set_color('white')
axes[1].spines['left'].set_color('white')
axes[1].bar_label(bars, labels=c_1897["Percentage"],fontname="Arial",size=12,weight=1000)

fig.set_size_inches(8.5, 11.5)
fig.suptitle('Соціальні статуси', fontsize=33, fontname="Arial")
Out[552]:
Text(0.5, 0.98, 'Соціальні статуси')
No description has been provided for this image

! У другому графіку використав корінь квадратний від значень популяції. Використав цей прийом, бо різниця дуже велика. І з квадратним коренем краще сприймається. Не використав log scale, бо маємо значення де логарифр дорівнює 0, а це в свою чергу дезінформує нас.

Колірна гамма використана тут дає змогу людям з різними типами кольорової сліпоти чітко розрізняти категорії. Приклади тут Fundamentals of Data Visualization

Аналіз результатів¶

  • Незважаючи на опір козацтва російській владі протягом 17-18 ст. За допомогою цих візуалізацій ми можемо прослідкувати подальші дії російської влади щодо козацтва. А саме шлях не повного знищення, а інтеграції козацької старшини та черні в життя російської імперії. Черні - в Армію, а стариши - в дворяни.
  • Також прослідковується селянська реформа 1861 р. Зменшення долі Прислуги(кріпаки) з 4% до менше ніж 1%(прислуга + державні селяни).
  • Загальні розподіл зберігся. З цікавого зʼявилися міщани, предвісник промислового перевороту та індустріального розвитку України.

Козацтво¶

Обробка та робота з даними

In [553]:
d_1897 = pd.read_csv("Final_DME/2.1_Дунаєць.xlsx - База людей.csv")
d_1897 = d_1897.loc[d_1897["Сословие, состояние или звание"] == "cossack"] # Тільки козаки
d_1897["Умеет ли читать"].value_counts()
literacy = pd.DataFrame(d_1897["Умеет ли читать"].value_counts())
literacy.reset_index(inplace=True)
literacy["Умеет ли читать"] = literacy["Умеет ли читать"].astype(str)
literacy.loc[literacy["Умеет ли читать"] == "0.0","Умеет ли читать"] = "Ні"
literacy.loc[literacy["Умеет ли читать"] == "1.0","Умеет ли читать"] = "Так"
literacy["Відсоток"] =  ((literacy["count"] / literacy["count"].sum()) * 100).round(2)
literacy
Out[553]:
Умеет ли читать count Відсоток
0 Ні 697 80.02
1 Так 174 19.98
In [554]:
d_1897 = pd.read_csv("Final_DME/2.1_Дунаєць.xlsx - База людей.csv")
d_1897 = d_1897.loc[d_1897["Сословие, состояние или звание"] == "cossack"] # Тільки козаки
d_1897.dropna(subset=["Обучение"],inplace=True)
d_1897.loc[d_1897["Обучение"].str.contains("zemsk"),"Обучение"] =  "Земські установи" # Обробка даних та перетворення їх на категорії
d_1897.loc[d_1897["Обучение"].str.contains("prichetnika"),"Обучение"] =  "Церковно приходські школи"
d_1897.loc[d_1897["Обучение"].str.contains("cerkovno"),"Обучение"] =  "Церковно приходські школи"
d_1897.loc[d_1897["Обучение"].str.contains("sel'skoe"),"Обучение"] =  "Сільські / Повітові заклади"
d_1897.loc[d_1897["Обучение"].str.contains("Glukhovskoe"),"Обучение"] =  "Сільські / Повітові заклади"
d_1897.loc[d_1897["Обучение"].str.contains("sel"),"Обучение"] =  "Сільські / Повітові заклади"
d_1897.loc[d_1897["Обучение"].str.contains("rural"),"Обучение"] =  "Сільські / Повітові заклади"
d_1897.loc[d_1897["Обучение"].str.contains("Home"),"Обучение"] =  "Домашнє навчання"
d_1897.loc[d_1897["Обучение"].str.contains("polku"),"Обучение"] =  "У полку"
d_1897["Обучение"].value_counts()
education = pd.DataFrame(d_1897["Обучение"].value_counts())
education.reset_index(inplace=True)
education["Emojis"] = pd.Series(["🏡","🏫","⛪️","🪖","🛖"]) * np.sqrt(education["count"]).astype(int) # Емоджі для графіка
education["X"] = 0
education["Sqrt(Кількості)"] = np.sqrt(education["count"]).astype(int)
education
Out[554]:
Обучение count Emojis X Sqrt(Кількості)
0 Земські установи 137 🏡🏡🏡🏡🏡🏡🏡🏡🏡🏡🏡 0 11
1 Сільські / Повітові заклади 13 🏫🏫🏫 0 3
2 Церковно приходські школи 13 ⛪️⛪️⛪️ 0 3
3 У полку 7 🪖🪖 0 2
4 Домашнє навчання 4 🛖🛖 0 2
In [555]:
d_1897 = pd.read_csv("Final_DME/2.1_Дунаєць.xlsx - База людей.csv")
d_1897 = d_1897.loc[d_1897["Сословие, состояние или звание"] == "cossack"] # Тільки козаки
d_1897.loc[d_1897["Профессия главное"].isna(),"Профессия главное"] = "Відсутня інформація"
d_1897.loc[d_1897["Профессия главное"].str.contains("farmer"),"Профессия главное"] = "Фермер" # Передивляємося дані основної професії та категоризуємо їх
d_1897.loc[d_1897["Профессия главное"].str.contains("with parents"),"Профессия главное"] = "На забезпеченні в батьків/опікунів"
d_1897.loc[d_1897["Профессия главное"].str.contains("with father"),"Профессия главное"] = "На забезпеченні в батьків/опікунів"
d_1897.loc[d_1897["Профессия главное"].str.contains("with mother"),"Профессия главное"] = "На забезпеченні в батьків/опікунів"
d_1897.loc[d_1897["Профессия главное"].str.contains("with stepfather"),"Профессия главное"] = "На забезпеченні в батьків/опікунів"
d_1897.loc[d_1897["Профессия главное"].str.contains("with stepfather"),"Профессия главное"] = "На забезпеченні в батьків/опікунів"
d_1897.loc[d_1897["Профессия главное"].str.contains("with ster-father"),"Профессия главное"] = "На забезпеченні в батьків/опікунів"
d_1897.loc[d_1897["Профессия главное"].str.contains("with brother"),"Профессия главное"] = "На забезпеченні в батьків/опікунів" # Для козацтва усі діти, якщо робити для інших верст треба передивлятися
d_1897.loc[d_1897["Профессия главное"].str.contains("with son"),"Профессия главное"] = "На хазяйстві" # На хазяйстві - Порається по дому, сидить з малолітніми дітьми, виконує мінімальну хатню робору через похилий вік 
d_1897.loc[d_1897["Профессия главное"].str.contains("with owner"),"Профессия главное"] = "На хазяйстві"
d_1897.loc[d_1897["Профессия главное"].str.contains("with grandson"),"Профессия главное"] = "На хазяйстві"
d_1897.loc[d_1897["Профессия главное"].str.contains("with nephew"),"Профессия главное"] = "На хазяйстві"
d_1897.loc[d_1897["Профессия главное"].str.contains("with children"),"Профессия главное"] = "На хазяйстві"
d_1897.loc[d_1897["Профессия главное"].str.contains("with stepson"),"Профессия главное"] = "На хазяйстві"
d_1897.loc[d_1897["Профессия главное"].str.contains("with husband"),"Профессия главное"] = "На хазяйстві"
d_1897.loc[d_1897["Профессия главное"].str.contains("with master"),"Профессия главное"] = "На хазяйстві"
d_1897.loc[d_1897["Профессия главное"].str.contains("Gornichnaya"),"Профессия главное"] = "Прислуга"
d_1897.loc[d_1897["Профессия главное"].str.contains("niania"),"Профессия главное"] = "Прислуга"
d_1897.loc[d_1897["Профессия главное"].str.contains("Prisluga"),"Профессия главное"] = "Прислуга"
d_1897.loc[d_1897["Профессия главное"].str.contains("Kukharka"),"Профессия главное"] = "Прислуга"
d_1897.loc[d_1897["Профессия главное"].str.contains("Povar"),"Профессия главное"] = "Прислуга"
d_1897.loc[d_1897["Профессия главное"].str.contains("Niania"),"Профессия главное"] = "Прислуга"
d_1897.loc[d_1897["Профессия главное"].str.contains("Dvornik"),"Профессия главное"] = "Прислуга"
d_1897.loc[d_1897["Профессия главное"].str.contains("rabotnik na othozhikh promyslakh"),"Профессия главное"] = "Працівник на відхожих промислах"
d_1897.loc[d_1897["Профессия главное"].str.contains("Na zarabotkach"),"Профессия главное"] = "Працівник на відхожих промислах"
d_1897.loc[d_1897["Профессия главное"].str.contains("Kucher"),"Профессия главное"] = "Інше"
d_1897.loc[d_1897["Профессия главное"].str.contains("Izvoshchik"),"Профессия главное"] = "Інше"
d_1897.loc[d_1897["Профессия главное"].str.contains("forest watcher"),"Профессия главное"] = "Інше"
d_1897.loc[d_1897["Профессия главное"].str.contains("krovel'shchik solomoyu"),"Профессия главное"] = "Інше"
d_1897.loc[d_1897["Профессия главное"].str.contains("Worker in the local priests house"),"Профессия главное"] = "Інше"
d_1897.loc[d_1897["Профессия главное"].str.contains("Blacksmith master"),"Профессия главное"] = "Інше"
main_profession = pd.DataFrame(d_1897["Профессия главное"].value_counts())
main_profession.reset_index(inplace=True)
main_profession
d_1897.loc[d_1897["Пол"] == "f", "Пол"] = "Female"
d_1897.loc[d_1897["Пол"] == "m", "Пол"] = "Male"
d_1897.rename(columns={"Пол" : "Стать"}, inplace=True)
main_profession
Out[555]:
Профессия главное count
0 Фермер 540
1 На забезпеченні в батьків/опікунів 273
2 На хазяйстві 28
3 Відсутня інформація 11
4 Прислуга 9
5 Інше 6
6 Працівник на відхожих промислах 4

Візуалізація даних

In [556]:
sex = ['Male', 'Female']
colors = ['#0096FF', '#FF69B4']

alt.Chart(d_1897).mark_bar().encode(
    x=alt.Y("Профессия главное:O", title="Заняття",axis=alt.Axis(labelAngle=-30)),
    y=alt.Y('count(Профессия главное):Q', title="Кількість Людей").scale(type="sqrt"),
    color=alt.Color("Стать", scale=alt.Scale(domain=sex, range=colors)),
    xOffset="Стать",
    tooltip=[alt.Tooltip('Профессия главное', title="Заняття"),
        alt.Tooltip('count(Профессия главное)', title="Кількість людей"),"Стать"]
    
).properties(width=1000,height=400, title="Основні заняття козаків та їх сімей"
).configure_axis(
    labelFontSize=10,
    titleFontSize=15,
    labelFontWeight= "bold"
).configure_title(
    fontSize=20,
    font='Arial'
).configure_legend(
    strokeColor='black',
    padding=10,
    cornerRadius=5,
    labelFontSize=10,
    titleFontSize=15
)
Out[556]:

! Тут також використав sqrt scale з аналогічних причин

In [557]:
lit_ability = ["Ні","Так"]
colors = ["#E69F00","#56B4E9"]

alt.Chart(literacy).mark_bar().encode(
    x=alt.X('sum(count)', title="Кількість Людей"),
    color=alt.Color('Умеет ли читать',scale=alt.Scale(domain=lit_ability,range=colors),title="Чи вміє читати?"),
    tooltip=[alt.Tooltip('sum(count)', title="Кількість людей"),
        "Відсоток"]
).properties(width=600,height=100)
Out[557]:
In [558]:
alt.Chart(education).mark_text(align='left').encode(
    alt.X('X:O', axis=None,scale=alt.Scale(range=[0,100])),
    alt.Y('Обучение:O',title="Місця навчання"),
    alt.SizeValue(40),
    text='Emojis',
    tooltip=[alt.Tooltip('count', title="Кількість учнів"),alt.Tooltip('Sqrt(Кількості)', title="sqrt(Кількість учнів)")],
).properties(width=600, height=300, title="Місця навчання козацтва"
).transform_calculate(
   value='0'
).configure_title(
    fontSize=20,
    font='Arial')
Out[558]:

! Теж sqrt

Аналіз результатів¶

  • Більшість козаків займалися фермерством. Чоловіки перавжно працювали у полі, на відхожих промислах, на інших посадах(колваль,кучер,церковник,лісничий). Більше жінок було на хазяйстві та у ролі прислуги(няньки, кухарки, покоївки)
  • Тільки 20% козацтва були грамотні.
  • Основними місцями отримання грамоти виступили земські школи, училища. Як додаткові місця навчання - це сільські, уїзні, церковні школи та навчання під час служби.

Дякую за увагу¶